package org.yunzhong.commontool.service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import com.deepoove.poi.XWPFTemplate;

@Service
public class HolidayApplyService {

    public String generate(Path excelPath, Path docPath, String date) throws IOException {
        try (InputStream excelInputStream = Files.newInputStream(excelPath);
                InputStream docInputStream = Files.newInputStream(docPath)) {
            return generate(excelInputStream, docInputStream, date);
        }
    }

    public String generate(InputStream excelInputStream, InputStream docInputStream, String date) throws IOException {
        Path templateFilePath = Paths.get("template.docx");
        if (Files.exists(templateFilePath)) {
            Files.delete(templateFilePath);
        }
        Files.copy(docInputStream, templateFilePath);

        Path logCsvpath = Paths.get("log" + System.currentTimeMillis() + ".csv");
        Files.createFile(logCsvpath);

        try (XSSFWorkbook workbook = new XSSFWorkbook(excelInputStream)) {
            XSSFSheet dateSheet = workbook.getSheet(date);
            int lastRowNum = dateSheet.getLastRowNum();
            XSSFRow dateRow = dateSheet.getRow(0);
            XSSFRow titleRow = dateSheet.getRow(1);
            short lastCellNum = titleRow.getLastCellNum();
            int rowIndex = 2;
            for (; rowIndex <= lastRowNum; rowIndex++) {
                XSSFRow dataRow = dateSheet.getRow(rowIndex);
                String numValue = dataRow.getCell(0).getRawValue();
                String nameValue = dataRow.getCell(1).getStringCellValue();
                String managerValue= dataRow.getCell(2).getStringCellValue();
                String insteadValue = dataRow.getCell(3).getStringCellValue();
                if (StringUtils.isEmpty(numValue) || StringUtils.isEmpty(nameValue)) {
                    break;
                }
                int cellIndex = 4;
                for (; cellIndex < lastCellNum; cellIndex++) {
                    String dateValue = parseDateCell(dateRow.getCell(cellIndex));
                    String amValue = parseCell(dataRow.getCell(cellIndex));
                    String pmValue = parseCell(dataRow.getCell(++cellIndex));
                    if (StringUtils.isEmpty(dateValue)) {
                        break;
                    }
                    if (StringUtils.isEmpty(amValue) && StringUtils.isEmpty(pmValue)) {
                        continue;
                    }
                    System.out
                            .println("name:" + nameValue + " date:" + dateValue + " am:" + amValue + " pm:" + pmValue );
                    Double holidayCount = Double.valueOf(StringUtils.isEmpty(amValue) ? "0" : amValue)
                            + Double.valueOf(StringUtils.isEmpty(pmValue) ? "0" : pmValue);
                    Map<String, Object> paramMap = new HashMap<>();
                    String lastDate = getLastDate(dateValue);
                    paramMap.put("name", nameValue);
                    paramMap.put("dept", "开发二部");
                    paramMap.put("apply_date", lastDate);
                    String holidayDetail = generateDetal(amValue, pmValue);
                    paramMap.put("holiday_detail", dateValue + holidayDetail);
                    paramMap.put("holiday_count", holidayCount);
                    paramMap.put("reason", "私事");
                    paramMap.put("instead", insteadValue);
                    paramMap.put("manager", managerValue);
                    try (XWPFTemplate xwpfTemplate = XWPFTemplate.compile(templateFilePath.toFile()).render(paramMap)) {
                        String fileName = nameValue + dateValue + "休假申请.docx";
                        Path filePath = Paths.get(fileName);
                        Files.deleteIfExists(filePath);

                        xwpfTemplate.writeToFile("./" + fileName);
                        Files.writeString(logCsvpath,
                                nameValue + "," + dateValue + "," + holidayDetail + ", success\r\n",
                                StandardOpenOption.APPEND);
                    } catch (Exception e) {
                        Files.writeString(logCsvpath, nameValue + "," + dateValue + "," + holidayDetail + ", error, "
                                + e.getLocalizedMessage(), StandardOpenOption.APPEND);
                    }
                }

            }
        }
        return null;
    }

    private String generateDetal(String amValue, String pmValue) {
        if (StringUtils.isNotEmpty(amValue) && StringUtils.isNotEmpty(pmValue)) {
            return "全天";
        }
        if (StringUtils.isNotEmpty(amValue)) {
            return "上午";
        }
        if (StringUtils.isNotEmpty(pmValue)) {
            return "下午";
        }
        return null;
    }

    private String getLastDate(String dateValue) {
        LocalDate lastDate = LocalDate.parse(dateValue, DateTimeFormatter.ISO_DATE).plusDays(-1);
        return lastDate.format(DateTimeFormatter.ISO_DATE);
    }

    private String parseDateCell(XSSFCell cell) {
        if (cell == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(cell.getDateCellValue());
    }

    private String parseCell(XSSFCell cell) {
        if (cell == null) {
            return null;
        }
        String cellValue = null;
        switch (cell.getCellType()) {
        case NUMERIC: // 数字
            if (DateUtil.isCellDateFormatted(cell)) {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                cellValue = df.format(cell.getDateCellValue());
            } else {
                cellValue = cell.getNumericCellValue() + "";
            }
            break;
        case STRING: // 字符串
            cellValue = cell.getStringCellValue();
            break;
        case BOOLEAN: // Boolean
            cellValue = cell.getBooleanCellValue() + "";
            break;
        case FORMULA: // 公式
            cellValue = cell.getCellFormula() + "";
            break;
        case BLANK: // 空值
            cellValue = "";
            break;
        case ERROR: // 故障
            cellValue = "非法字符";
            break;
        default:
            cellValue = "未知类型";
            break;
        }
        return cellValue;
    }

    public String generate(Path excelPath, Path docPath) throws IOException {
        String date = null;
        try (InputStream excelInputStream = Files.newInputStream(excelPath);
                XSSFWorkbook workbook = new XSSFWorkbook(excelInputStream)) {
            int sheetCount = workbook.getNumberOfSheets();
            while (sheetCount >= 0) {
                XSSFSheet sheetAt = workbook.getSheetAt(sheetCount - 1);
                date = sheetAt.getSheetName();
                if (StringUtils.isNumeric(date)) {
                    break;
                }
                sheetCount--;
            }
        }
        return generate(excelPath, docPath, date);
    }
}
